package com.qububu.utils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

/**
 * @author ZCW
 * 
 * @详情 系统常用工具包
 * */
public class SystemUtil {

	/**
	 * @功能 获取请求者IP
	 * */
	public static String getRequestIp(HttpServletRequest req) {
		
		String ip = req.getHeader("x-forwarded-for");
		
		if (SystemValidate.strIsNull(ip) || "unknown".equalsIgnoreCase(ip)) {
			
			ip = req.getHeader("Proxy-Client-IP");
		}
		
		if (SystemValidate.strIsNull(ip) || "unknown".equalsIgnoreCase(ip)) {
			
			ip = req.getHeader("WL-Proxy-Client-IP");
		}
		
		if (SystemValidate.strIsNull(ip) || "unknown".equalsIgnoreCase(ip)) {
		
			ip = req.getHeader("X-Real-IP");
		}
		
		if (SystemValidate.strIsNull(ip) || "unknown".equalsIgnoreCase(ip)) {
			
			ip = req.getRemoteAddr();
		}
		
		if (!SystemValidate.strIsNull(ip) && !"unknown".equalsIgnoreCase(ip)) {
			//多级代理情况
			int end = ip.indexOf(",");
			
			if (end != -1) {
				
				ip = ip.substring(0, end);
			}
		}
		
		return ip;
	}
	
	/**
	 * @功能 生成时间戳加两位随机数
	 * */
	public static String createTimestamp() {
		
		String timestamp = String.valueOf(DateUtil.getDateMillisecond(new Date()));
		
		timestamp = timestamp +"-"+ new Random().nextInt(100);
		
		return timestamp;
	}
	
	/**
	 * @功能 加密页面敏感信息
	 * */
	public static String encrypt(String oriStr) {
		return Base64Util.idHandle(oriStr, SystemConstants.PASSWORD_KEY, SystemConstants.ENCIPHERMENT);
	}	
		
	/**
	 * @功能 解密页面敏感信息
	 * */
	public static String decrypt(String cypherStr) {
		return Base64Util.idHandle(cypherStr, SystemConstants.PASSWORD_KEY, SystemConstants.DECIPHERING);
	}
	
	/**
	 * @功能 过滤字符串中非法信息并替换
	 * @param context 需要过滤掉非法字符的内容
	 * @return String 替换完成的字符串内容
	 * */
	public static final String convertSpecialMark(String context) {
		context = context.replaceAll("<", "&lt");
		context = context.replaceAll(">", "&gt");
		context = context.replaceAll("[\\s]", "&nbsp;");
		
		return context;
	}
	
	/**
	 * 移除所有<, >, 
	 * */
	
	/**
	 * @功能 从繁杂(未处理过,包含<img>等关键字的内容)中提出文章的概要
	 * @param context 需要提概要的文章内容
	 * @return String 文章概要内容
	 * */
	public static final String getSummaryText(String content, int length) {
		if (content.length() > length) {
//			content = removeATagFromHtml(content);
//			content = removeImgTagFromHtml(content);
			content = removeAllTagFromHtml(content);
			content = content.substring(0, length - 1) + "...";
//			content = convertSpecialMark(content);
		}
		
		return content;
	}
	
	/**
	 * 去除script脚本
	 * */
	public static final String removeAllScriptFromHtml(String html) {
		String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>";
		
		return html.replaceAll(regEx_script, "");
	}
	
	/**
	 * 去除<a>标签
	 * */
	public static String removeATagFromHtml(String html) {
		String result = html.replaceAll("<\\s*a\\s+([^>]*)>", "");
		result = result.replaceAll("<\\s*/\\s*a\\s*>", "");
		return result;
	}
	
	/**
	 * 去除所有<>标签
	 * */
	public static final String removeAllTagFromHtml(String html) {
		String result = html.replaceAll("<\\s*([a-zA-Z]*)\\s*(\\w||\\W)*\\s*([/]*)\\s*>", "");
		result = result.replaceAll("<\\s*/\\s*([a-zA-Z]*)\\s*>", "");
		
		return result;
	}
	
	/**
	 * @功能 给出文章中的概略图
	 * @param context 需要取出图片的内容
	 * @param servletContxet站点访问路径(request.getContextPath())
	 * */
	public static final String getSummaryPicUrl(String context, String servletContext) {
		List<String> imagePathList = getImgTagListFromHtml(context);
		for (String elem : imagePathList) {
			if (!elem.contains(servletContext + "/" + SystemConstants.SYSTEM_RESOURCE_PATH_BASE) ) {
				
				return elem;
			}
		}
		
		return null;
	}
	
	/**
	 * @功能 提取字符串中的图片的url
	 * @param content 需要取出图片的内容
	 * @return List 取出的图片的url
	 * */
	public static final List<String> getImgTagListFromHtml(String content) {
		
		Matcher imgCotentMatcher = Pattern.compile("<\\s*img\\s+([^>]*)>").matcher(content);
		
		List<String> imgUrlList = new ArrayList<String>();
		
		Pattern imgUrlPattern = Pattern.compile("src\\s*=\\s*\"([^\"]+)\"");
		
		while(imgCotentMatcher.find()) {
		
			Matcher imgUrlMatcher = imgUrlPattern.matcher(imgCotentMatcher.group());
	        if(imgUrlMatcher.find()){
	        
	        	String srcAttr = imgUrlMatcher.group();
	        	imgUrlList.add(srcAttr.substring(srcAttr.indexOf('"')+1, srcAttr.lastIndexOf('"')));  
	        }  
		}	

		return imgUrlList;
	}
	
	/**
	 * @功能 去除字符串中的图片内容
	 * @param context 需要去除图片的字符串
	 * @return String 去除了图片的字符串
	 * */
	public static String removeImgTagFromHtml(String html) {
		Matcher imgCotentMatcher = Pattern.compile("<\\s*img\\s+([^>]*)>").matcher(html);
		return imgCotentMatcher.replaceAll("");
	}
	
	/**
	 * @功能 获取Object[]中的数据并设置成PreparedStatement
	 * @param needSetValuesPreparedStatement 需要设置值的PreparedStatement
	 * @param Object[] 值的集合, 只针对int、String、long类型的值
	 * @return 设置好了值的PreparedStatement
	 * @throws SQLException 
	 * */
	private static final PreparedStatement setValuesToPreparedStatement(PreparedStatement needSetValuesPreparedStatement, Object[] objs) throws SQLException {
		
		for (Object obj : objs) {
			
			int insertNum = 0;
			
			if (obj instanceof Integer) {
				
				needSetValuesPreparedStatement.setInt(++ insertNum, ParamConverter.convertToInteger(String.valueOf(obj) ) );
			} else if (obj instanceof String) {
				
				needSetValuesPreparedStatement.setString(++ insertNum, String.valueOf(obj) );
			} else if (obj instanceof Long) {
				
				needSetValuesPreparedStatement.setLong(++ insertNum, ParamConverter.convertToLongObj(String.valueOf(obj) ) );
			} else if (SystemValidate.isEmpty(obj)) {
				
				needSetValuesPreparedStatement.setString(++ insertNum, String.valueOf(obj));
			} else {
				
				throw new SQLException("Object中设置的值的属性不是Long, String, Integer中的任何一种");
			}
		}
		
		return needSetValuesPreparedStatement;
	}
	
	/**
	 * @功能 执行sql语句并返回最后一次插入生成的id
	 * @param JdbcTemplate
	 * @param String sql 需要执行的sql语句
	 * @param Object[] values值的集合, 只针对int、String、long类型的值
	 * @return Long 最新插入一行对应的id
	 * */
	public static final Long doUpdateGetLastInsertId (JdbcTemplate jdbcTemplate, final String sql, final Object[] values) {
		
		KeyHolder generatedKeyHolder = new GeneratedKeyHolder();
		
		jdbcTemplate.update(new PreparedStatementCreator() {
			
			public PreparedStatement createPreparedStatement(Connection connection)
					throws SQLException {
				
				PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
				
				ps = setValuesToPreparedStatement(ps, values);
				
				return ps;
			}
			
		}, generatedKeyHolder);
		
		Long generatedId = generatedKeyHolder.getKey().longValue();
		
		return generatedId;
	}
	
	/**
	 *  得到UUID
	 * @return String
	 * 				返回32位的UUID，去除了中间的连字号
	 * @author ZCW
	 */
	public static final String getUUIDString() {
		return UUID.randomUUID().toString().replaceAll("-", "");
	}
	
	/**
	 * @功能 返回重定向的绝对路径
	 * @param relativePath, 需要跳转到的绝对路径地址
	 * */
	/*public static final String getRedirectUrl(HttpServletRequest req, String relativePath) {
		
		StringBuffer returnUrl = new StringBuffer();
		returnUrl.append("redirect:");
		returnUrl.append(req.getContextPath());
		returnUrl.append(relativePath);
		
		return returnUrl.toString();
	}*/
	
	/**
	 * 测试方法正确性
	 * */
	public static void main(String args[]) {
		/*String st =  "abc<img src=\"www.baidu.com\" alt='找找看' />cde不刚好顺逆<script>alert('1234')</script><img src=\"www.google.com\" alt='找找看' />";
		List<String> l = getImgTagListFromHtml(st);
		String ss = removeImgTagFromHtml(st);
		String s = convertSpecialMark(ss);
		
		for (String url : l) {
		
			System.out.println("\n-url--"+url+"--\n");
		}
		
		System.out.println("\n-移除图片后--"+ss+"--\n");
		
		System.out.println("\n-过滤完成后--"+s+"--\n");
		
		String a = "<a href=\"www.baidu.com\">去百度看看</a>";
		
		System.out.println("去a结果为------" + removeATagFromHtml(a) +"-----------");
		
		String img = "<img src=\"www.baidu.com\"/>去百度看看";
		
		System.out.println("去img结果为------" + removeImgTagFromHtml(img) +"-----------");
		
		String html = "<img/>不知道<a>行不行</a>就是<span style=\"color: red; background: green;\">span中的内容</span>啊啊啊<b>这是b里面的内容</b>";
		
		System.out.println("取出<>后的内容是：----" + removeAllTagFromHtml(html));*/
		
		/*String s = "1XDIWAcxyxGbpvAyPKU_wg";
		System.out.println("------结果是-----"+decrypt(s));
		*/
		String htmlStr = "<a>a</a>b<img />c<b>d</b><span style='position: absolute'>e</span>";
		System.out.println("----" +removeAllTagFromHtml(htmlStr)+"----");
	}
}

